finally use TrackMouseEvent (only if the new window not known to Gdk) to
authorHans Breuer <hans@breuer.org>
Thu, 7 Aug 2003 15:10:16 +0000 (15:10 +0000)
committerHans Breuer <hans@src.gnome.org>
Thu, 7 Aug 2003 15:10:16 +0000 (15:10 +0000)
2003-08-07  Hans Breuer  <hans@breuer.org>

* gdk/win32/gdkevents-win32.c : finally use TrackMouseEvent
(only if the new window not known to Gdk) to get proper
leave notification, and get rid of the wrong placed
tooltips, bug #102283

(gdk_event_translate) : small code reordering to not get
GDK_MOTION_NOTIFY for still mouse and get back tooltips on
menus, bug #117367

ChangeLog
ChangeLog.pre-2-10
ChangeLog.pre-2-4
ChangeLog.pre-2-6
ChangeLog.pre-2-8
gdk/win32/gdkevents-win32.c

index de8910dba0c9aa09c22394eebf1a5805ead5f215..bc82a58bb4a8219d7741967dfa12a6db09a4c302 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+2003-08-07  Hans Breuer  <hans@breuer.org>
+
+       * gdk/win32/gdkevents-win32.c : finally use TrackMouseEvent
+       (only if the new window not known to Gdk) to get proper
+       leave notification, and get rid of the wrong placed 
+       tooltips, bug #102283
+       (gdk_event_translate) : small code reordering to not get
+       GDK_MOTION_NOTIFY for still mouse and get back tooltips on 
+       menus, bug #117367
+
 2003-08-07  Tor Lillqvist  <tml@iki.fi>
 
        * gdk/gdk.def
index de8910dba0c9aa09c22394eebf1a5805ead5f215..bc82a58bb4a8219d7741967dfa12a6db09a4c302 100644 (file)
@@ -1,3 +1,14 @@
+2003-08-07  Hans Breuer  <hans@breuer.org>
+
+       * gdk/win32/gdkevents-win32.c : finally use TrackMouseEvent
+       (only if the new window not known to Gdk) to get proper
+       leave notification, and get rid of the wrong placed 
+       tooltips, bug #102283
+       (gdk_event_translate) : small code reordering to not get
+       GDK_MOTION_NOTIFY for still mouse and get back tooltips on 
+       menus, bug #117367
+
 2003-08-07  Tor Lillqvist  <tml@iki.fi>
 
        * gdk/gdk.def
index de8910dba0c9aa09c22394eebf1a5805ead5f215..bc82a58bb4a8219d7741967dfa12a6db09a4c302 100644 (file)
@@ -1,3 +1,14 @@
+2003-08-07  Hans Breuer  <hans@breuer.org>
+
+       * gdk/win32/gdkevents-win32.c : finally use TrackMouseEvent
+       (only if the new window not known to Gdk) to get proper
+       leave notification, and get rid of the wrong placed 
+       tooltips, bug #102283
+       (gdk_event_translate) : small code reordering to not get
+       GDK_MOTION_NOTIFY for still mouse and get back tooltips on 
+       menus, bug #117367
+
 2003-08-07  Tor Lillqvist  <tml@iki.fi>
 
        * gdk/gdk.def
index de8910dba0c9aa09c22394eebf1a5805ead5f215..bc82a58bb4a8219d7741967dfa12a6db09a4c302 100644 (file)
@@ -1,3 +1,14 @@
+2003-08-07  Hans Breuer  <hans@breuer.org>
+
+       * gdk/win32/gdkevents-win32.c : finally use TrackMouseEvent
+       (only if the new window not known to Gdk) to get proper
+       leave notification, and get rid of the wrong placed 
+       tooltips, bug #102283
+       (gdk_event_translate) : small code reordering to not get
+       GDK_MOTION_NOTIFY for still mouse and get back tooltips on 
+       menus, bug #117367
+
 2003-08-07  Tor Lillqvist  <tml@iki.fi>
 
        * gdk/gdk.def
index de8910dba0c9aa09c22394eebf1a5805ead5f215..bc82a58bb4a8219d7741967dfa12a6db09a4c302 100644 (file)
@@ -1,3 +1,14 @@
+2003-08-07  Hans Breuer  <hans@breuer.org>
+
+       * gdk/win32/gdkevents-win32.c : finally use TrackMouseEvent
+       (only if the new window not known to Gdk) to get proper
+       leave notification, and get rid of the wrong placed 
+       tooltips, bug #102283
+       (gdk_event_translate) : small code reordering to not get
+       GDK_MOTION_NOTIFY for still mouse and get back tooltips on 
+       menus, bug #117367
+
 2003-08-07  Tor Lillqvist  <tml@iki.fi>
 
        * gdk/gdk.def
index 8d97a5c655603256a35287175f26815e9067d883..d574b9eb7ed04a1751078f6e7f72f3a4ddc78896 100644 (file)
  * otherwise would make it possible to reliably generate
  * GDK_LEAVE_NOTIFY events, which would help get rid of those pesky
  * tooltips sometimes popping up in the wrong place.
+ *
+ * Update: a combination of TrackMouseEvent, GetCursorPos and 
+ * GetWindowPos can and is actually used to get rid of those
+ * pesky tooltips. It should be possible to use this for the
+ * whole ENTER/LEAVE NOTIFY handling but some platforms may
+ * not have TrackMouseEvent at all (?) --hb
  */
 
 #include "config.h"
@@ -151,6 +157,46 @@ assign_object (gpointer lhsp,
     }
 }
 
+static void
+track_mouse_event (DWORD dwFlags, HWND hwnd)
+{
+  typedef BOOL (WINAPI *PFN_TrackMouseEvent) (LPTRACKMOUSEEVENT);
+  static PFN_TrackMouseEvent p_TrackMouseEvent = NULL;
+  static int once = 0;
+
+  if (!once)
+    {
+      HMODULE user32;
+      HINSTANCE commctrl32;
+
+      user32 = GetModuleHandle ("user32.dll");
+      if ((p_TrackMouseEvent = (PFN_TrackMouseEvent)GetProcAddress (user32, "TrackMouseEvent")) == NULL)
+        {
+          if ((commctrl32 = LoadLibrary ("commctrl32.dll")) != NULL)
+       p_TrackMouseEvent = (PFN_TrackMouseEvent)
+         GetProcAddress (commctrl32, "_TrackMouseEvent");
+        }
+      if (p_TrackMouseEvent != NULL)
+        GDK_NOTE (EVENTS, g_print ("Using TrackMouseEvent to detect leave events\n"));
+
+      once = 1;
+    }
+
+  if (p_TrackMouseEvent)
+    {
+      TRACKMOUSEEVENT tme;
+      tme.cbSize = sizeof(TRACKMOUSEEVENT);
+      tme.dwFlags = dwFlags;
+      tme.hwndTrack = hwnd;
+      tme.dwHoverTime = HOVER_DEFAULT; /* not used */
+
+      if (!p_TrackMouseEvent (&tme))
+        WIN32_API_FAILED ("TrackMouseEvent");
+      else
+        GDK_NOTE (EVENTS, g_print("TrackMouseEvent (%p, %s)\n", hwnd, dwFlags == TME_CANCEL ? "cancel" : "leave"));
+    }
+}
+
 gulong
 _gdk_win32_get_next_tick (gulong suggested_tick)
 {
@@ -1196,6 +1242,11 @@ synthesize_leave_event (GdkWindow      *window,
   else
     synthesize_enter_or_leave_event (window, msg, GDK_LEAVE_NOTIFY, mode, detail, current_x, current_y);
 
+  /* This would only make sense if the WM_MOUSEMOVE messages would come
+   * before the respective WM_MOUSELEAVE message, which apparently they
+   * do not.
+  track_mouse_event (TME_CANCEL, msg->hwnd);
+   */
 }
   
 static void
@@ -1221,6 +1272,8 @@ synthesize_enter_event (GdkWindow      *window,
       ScreenToClient (GDK_WINDOW_HWND (window), &pt);
     }
   synthesize_enter_or_leave_event (window, msg, GDK_ENTER_NOTIFY, mode, detail, pt.x, pt.y);
+
+  track_mouse_event (TME_LEAVE, msg->hwnd);
 }
   
 static void
@@ -2435,6 +2488,12 @@ gdk_event_translate (GdkDisplay *display,
                      doesnt_want_button_motion))
        break;
 
+      if (GDK_WINDOW_DESTROYED (window))
+       break;
+
+      if (window != orig_window)
+       translate_mouse_coords (orig_window, window, msg);
+
       /* If we haven't moved, don't create any event.
        * Windows sends WM_MOUSEMOVE messages after button presses
        * even if the mouse doesn't move. This disturbs gtk.
@@ -2444,15 +2503,9 @@ gdk_event_translate (GdkDisplay *display,
          GET_Y_LPARAM (msg->lParam) == current_y)
        break;
 
-      if (GDK_WINDOW_DESTROYED (window))
-       break;
-
       event = gdk_event_new (GDK_MOTION_NOTIFY);
       event->motion.window = window;
       event->motion.time = _gdk_win32_get_next_tick (msg->time);
-      if (window != orig_window)
-       translate_mouse_coords (orig_window, window, msg);
-
       event->motion.x = current_x = (gint16) GET_X_LPARAM (msg->lParam);
       event->motion.y = current_y = (gint16) GET_Y_LPARAM (msg->lParam);
       _gdk_windowing_window_get_offsets (window, &xoffset, &yoffset);
@@ -2485,6 +2538,32 @@ gdk_event_translate (GdkDisplay *display,
 
       break;
 
+    case WM_MOUSELEAVE:
+      {
+        HWND wndnow;
+        POINT pt;
+
+        if (!GetCursorPos (&pt))
+          WIN32_API_FAILED ("GetCursorPos");
+        wndnow = WindowFromPoint (pt);
+
+        if (!gdk_win32_handle_table_lookup ((GdkNativeWindow) wndnow))
+          {
+            /* we are only interested if we don't know the new window */
+            GDK_NOTE (EVENTS, g_print ("WM_MOUSELEAVE: %p %d (%d,%d)\n",
+                                       msg->hwnd, HIWORD (msg->wParam), pt.x, pt.y));
+            synthesize_enter_or_leave_event (current_window, msg, 
+                GDK_LEAVE_NOTIFY, GDK_CROSSING_NORMAL, GDK_NOTIFY_UNKNOWN, 
+                current_x, current_y);
+          }
+        else
+          {
+            GDK_NOTE (EVENTS, g_print ("WM_MOUSELEAVE: %p %d (%d,%d) ignored\n",
+                                       msg->hwnd, HIWORD (msg->wParam), pt.x, pt.y));
+          }
+      }
+      return_val = TRUE;
+      break;
     case WM_MOUSEWHEEL:
       GDK_NOTE (EVENTS, g_print ("WM_MOUSEWHEEL: %p %d\n",
                                 msg->hwnd, HIWORD (msg->wParam)));